2026년, 왜 다시 코인을 보기 시작했나 저는 2026년에는 코인을 좀 더 진지하게 보기로 했습니다. 코인이 단순한 유행이 아니라 돈과 금융 인프라가 바뀌는 흐름과 맞물려 있다고 느꼈기 때문입니다. 그 흐름을 결정할 큰 이벤트 중 하나가 CLARITY Act 같은 규제 정리라고도 봤습니다. CLARITY Act가 뭐길래? 쉽게 말하면, 미국이 코인 시장에 대해 이런 질문들에 공식 답을 내려서 시장 규칙을 정리하려는 겁니다. 이게 왜 중요하냐면 규칙이 정해진다면 그래서 저는 규제가 단순 호재는 아니지만 시장을 계속 눌러왔던 불확실성 할인 을 줄이는 쪽으로는 작동할 수 있다고 봅니다. 코인을 보는 관점 저는 코인이라는 게 참 애매하다고 느낍니다. 코인의 가치와 가격을 매기는 게 참 어렵습니다. 코인 자체가 아무 쓸데가 없는 건 아닙니다. 송금에도 쓰이고, 결제나 정산 같은 용도로 쓰이기도 합니다. 하지만 저는 결론부터 이렇게 생각합니다. 코인은 쓴다 는 이유만으로는 가격이 설명되지 않습니다. 오히려 대부분의 경우, 사용량이 늘어도 가격이 따라오지 않습니다. 수수료 소각이 있든, 스테이킹이 있든, 담보 수요가 있든 마찬가지입니다. 그런 요소들이 존재하더라도, 그 규모가 작거나 우회가 가능하면 가격에 남는 힘은 제한적입니다. 사용이 늘수록 공급이 같이 늘어나는 구조라면, 오히려 매도 압력이 커질 수도 있습니다. 그래서 코인 가격은 보통 이런 흐름으로 더 잘 설명됩니다. 기대(서사) → 매수 → 가격 상승 가격 상승 → 신뢰/담보성/인지도 강화 강화된 신뢰 → 더 큰 매수 즉, 코인은 쓸모가 가격을 만든다 기보다 시장이 그 자산을 대표 자산처럼 취급하고, 담보처럼 믿기 시작할 때 가격이 만들어지는 경우가 많습니다. 그래서 코인은 쓰이긴 하지만 굳이 비쌀 필요는 없지 않나 라는 말은 꽤 맞는 말입니다. 코인이 쓰인다는 사실과, 그 코인이 비싸야 한다는 이유는 별개입니다. 그럼에도 지금 당장 가격은 오르고 있습니다. 코인이 제도권 안에 들어온 뒤에 어떻게 될지는 잘 모르겠습니다. 변동성이 줄어들면서 기대가 사라질 수도 있고, 반대로 서사가 더 붙으면서 가격이 더 움직일 수도 있습니다. 저는 이 시장을 확신으로 보지는 않습니다. 다만 코인이 서사와 신뢰로 움직이는 자산이라면, 그 흐름이 살아 있는 구간에서는 일부를 담아볼 수 있다고 봅니다. 지금은 가격이 한 번 크게 눌린 뒤라서, 저는 반등 구간을 염두에 두고 소액으로 매수해보려고 합니다. 결국 저는 각 코인을 볼 때 서사를 출발점으로 보되, 그 서사가 가격으로 남는 구조인지까지 확인하려고 합니다. 블록체인 기초: 코인은 도대체 뭘까? 블록체인은 거래 장부이고, 코인은 그 장부 위에서 쓰이는 자산입니다. 이 장부가 실제로 돌아가는 네트워크를 보통 메인넷이라고 부릅니다. 대부분의 경우 이 메인넷 자체가 L1입니다 블록체인에서 장부는 그냥 존재한다고 유지되지 않고, 누군가 거래를 검증하고 기록을 확정해야 하고, 그 과정에는 비용이 듭니다. 그렇기에 정확히 말하면 장부의 최종본을 남기는 중심 도로가 L1이며, 그 중심 도로를 이용하는 데 드는 수수료를 코인으로 지급하는 겁니다. 즉 Bitcoin이라는 L1 네트워크에서 거래를 하려면 수수료를 BTC라는 코인으로 지불해야 하고, 그 수수료는 거래를 블록에 포함시키는 채굴자에게 지급됩니다. 그러면 L1이라는 도로에 모든 사용자가 몰리면 교통 체증이 일어납니다. 이를 해결하기 위해 나온 게 L2입니다. 즉 L1이 붐빌 때 우회해서 쓰는 골목길이라고 생각하면 됩니다. 코인에서 지갑의 개념이란 위에서 메인넷, L1, L2를 설명했으니, 그럼 우리가 흔히 말하는 코인 지갑이란 뭘까요. 코인의 기록은 장부에 있고, 지갑은 그 기록을 움직일 수 있는 키를 관리합니다. 그래서 제 지갑에 코인이 있다는 말은, 제가 장부에 찍힌 그 기록을 움직일 수 있는 열쇠를 담 있다고 생각하면 됩니다. DeFi DeFi는 블록체인 위에 올라가 있는 금융 프로그램을 말합니다. 대출, 예치, 스왑 같은 기능이 사람이 처리하는 게 아니라, 미리 정해진 규칙대로 자동 실행됩니다. 사용자는 화면에서 버튼을 누르지만, 실제로는 지갑이 거래를 만들고 네트워크로 보내고, 그 거래가 스마트 컨트랙트를 실행시켜 담보를 잠그거나 대출을 실행합니다. DeFi 대출은 대부분 담보 기반이고, 담보 가치가 떨어지면 자동으로 청산될 수 있습니다. 그리고 DeFi는 자동이라고 해서 자동으로 안전한 건 아닙니다. 코드 취약점, 잘못된 승인, 가짜 사이트 같은 리스크가 있고, 사고가 나면 되돌리기 어려운 경우도 있습니다. 관심을 갖고 있는 코인 이제부터는 각 코인별로 제가 바라보는 관점을 생략 없이 적어보겠습니다. Bitcoin(BTC) 비트코인은 서사가 가격으로 남는 구조가 가장 단순한 코인입니다. 디지털 금, 그리고 대표 담보 자산이라는 서사입니다. 이 서사가 가격으로 남는 경로는 두 가지로 정리됩니다. 하락 구간에서는 수요가 다시 중심 자산으로 모이는 경향이 있습니다. 저는 그 중심이 비트코인이라고 생각합니다. 그래서 비트코인을 우선으로 매수하려고 합니다. XRPL(XRP) XRP를 볼 때 가장 먼저 잡히는 서사는 브릿지 입니다. XRPL이 국경 간 송금과 정산에서 중간 레일 역할을 할 수 있고, CBDC가 커질수록 서로 다른 시스템을 연결하는 브릿지가 필요해질 수 있다는 이야기입니다. 서사 자체는 그럴듯합니다. 문제는 그 서사가 곧바로 XRP 가격 상승으로 이어지느냐입니다. 저는 XRP에서 이 구간이 가장 어렵다고 느낍니다. 1) 브릿지 서사가 가격으로 남기 어려운 이유 브릿지 자산의 핵심은 필수냐 보다 얼마나 오래 들고 있느냐 에 가깝습니다. 브릿지는 효율적으로 돌아갈수록 보유 시간이 짧아집니다. 송금 순간에 XRP를 사고, 짧은 시간 들고 있다가, 도착 즉시 다시 파는 구조가 이상적입니다. 이 방식은 결제 효율에는 유리할 수 있지만, 가격에는 애매하게 작동할 수 있습니다. 사용량이 늘어도 장기 보유 수요가 늘지 않을 수 있기 때문입니다. 즉 결제량이 늘어나는 것과, 사람들이 XRP를 오래 들고 있어야 하는 것은 별개가 될 수 있습니다. 그래서 XRP는 실사용이 늘면 오른다 로 단순화하기가 특히 어렵다고 봅니다. 2) 기관이 실제로 쓰려면 변동성이 가장 큰 장애물입니다 XRPL이 기술적으로 빠르냐보다, 기관 입장에서는 리스크가 먼저입니다. 결제에서 제일 큰 리스크는 변동성입니다. 브릿지 구조는 보유 시간이 짧아도, 큰 금액이 오갈수록 그 짧은 시간의 가격 변동이 바로 손실이 될 수 있습니다. 그래서 기관이 실제로 쓰려면 아래 같은 조건이 필요해집니다. 결국 XRP가 결제 레일에서 쓰이려면 기술보다 시장 구조(유동성/헤지/마켓메이킹)와 규제가 먼저 받쳐야 한다고 봅니다. 여기서 역설이 하나 생깁니다. 그 정도로 시장 구조가 성숙하면 변동성은 줄어드는 방향으로 갈 가능성이 큽니다. 그 경우 XRP가 결제용 도구로 안정화되면서, 가격이 폭발적으로 급등해야 할 필연성은 오히려 약해질 수도 있습니다. 3) CBDC 브릿지 서사는 매력적이지만, 독점하기는 어렵습니다 CBDC가 커지면 상호운용 문제가 생길 수 있고, 브릿지가 필요해질 수 있습니다. 다만 그 브릿지가 반드시 XRP여야 한다고 단정하기는 어렵습니다. 즉 브릿지 필요가 곧 XRP 필요로 직결된다고 보기에는 대체 경로가 많습니다. 4) XRPL 수수료 소각은 존재하지만, 가격 엔진이 되기엔 약합니다 XRPL의 거래 수수료는 소각되는 구조입니다. 다만 저는 이게 가격을 밀어 올리는 핵심 동력이라고 보지는 않습니다. 수수료 단위가 매우 작고, 사용량이 늘어도 공급을 의미 있게 줄일 정도의 소각으로 이어지기 어렵기 때문입니다. 그래서 소각이 있으니 오른다는 설명은 XRP에서는 특히 부족하다고 느낍니다. 5) 결론: 서사는 크지만, 가격으로 남는 구조는 아직 애매합니다 XRP의 브릿지 서사는 이해됩니다. 다만 그 서사가 곧바로 가격 상승 논리로 이어지지는 않는다고 생각합니다. 그래서 저는 XRP를 정책에 따라 크게 흔들릴 수 있는 옵션 성격의 자산으로 봅니다. 비중은 작게 가져가고, 공격적으로 베팅하지 않으려고 합니다. Ethereum(ETH) 이더리움은 코인 중에서 가치가 가장 논리적으로 보이는 코인이라고 생각합니다. 이더리움의 서사는 기반 인프라입니다. DeFi와 스테이블코인 같은 온체인 금융이 굴러가는 기본 레이어라는 서사입니다. 그런데 이더리움은 여기서부터가 어렵습니다. 생태계가 커지는 것과, ETH 가격이 강해지는 것은 같은 문제로 단정하기 어렵기 때문입니다. 이더리움은 L2가 커질수록 오히려 성공할 수도 있고, 반대로 L2가 커질수록 ETH에 남는 가치가 얇아질 수도 있습니다. 그래서 저는 ETH를 볼 때, 가치가 ETH에 남는 경로가 어디인지부터 확인하려고 합니다. 제가 보기엔 그 경로는 네 갈래입니다. 이 네 갈래가 같이 강해질수록 ETH는 기반 자산으로 강해질 수 있다고 봅니다. 반대로 이 중 일부가 L2나 다른 곳으로 새면, 생태계가 커져도 ETH 가격은 애매해질 수 있습니다. 1) L1 수수료와 소각: L2가 커질수록 연결이 끊길 수도 있습니다 이더리움의 강점 중 하나는 수수료가 발생하면 소각이 동반된다는 점입니다. 사용이 강한 구간에서는 소각이 늘고, 공급이 줄어드는 구간도 나올 수 있습니다. 하지만 L2 시대에는 질문이 달라집니다. 사용자는 L2에서 거래하고, 수수료는 우선 L2에 쌓입니다. L1에 남는 건 “사용자 거래 수수료”가 아니라 L2가 올리는 정산과 데이터 비용입니다. L2가 커질수록 L1에 정산을 더 올리긴 합니다. 다만 L2가 정산을 얼마나 압축해서 올리느냐에 따라, 거래가 늘어나는 속도만큼 L1 수수료가 같이 늘지 않을 수도 있습니다. 결국 핵심은 이겁니다. L2가 성장할수록 L1 수수료와 소각이 얼마나 두껍게 따라오느냐입니다. 저는 이 지점이 ETH를 제일 헷갈리게 만드는 핵심이라고 느낍니다. 2) MEV: 돈이 어디에 쌓이느냐가 중요합니다 여기서부터는 DEX 거래가 어떤 방식으로 처리되는지부터 이해해야 합니다.DEX에서 “매수”는 CEX처럼 호가창에 주문을 거는 게 아니라, 환전(스왑)에 가깝습니다. 즉 “USDT로 이 토큰을 바꿔줘”라는 요청을 보내는 구조입니다.그래서 내가 원하는 가격을 딱 지정해서 사는 게 아니라, 지금 풀(환전소)의 환율로 바뀌는 방식입니다. 대신 “이 정도까지는 괜찮다”는 허용 범위(슬리피지)를 설정해서,가격이 너무 불리해지면 거래가 취소되게 만들 수 있습니다. 이제 거래 과정은 이렇게 흘러갑니다. 매수 버튼 클릭 트랜잭션 전송 멤풀에서 대기 MEV가 발생하는 방식(아주 쉽게) 이더리움 채굴자(=블록 생산자, 현재는 보통 “검증자”라고도 부름)가 선택 블록 생성 체인에 붙고 확정 정리 3) 스테이킹: ETH가 “운영 자산”이 될 수 있는 경로입니다 이더리움은 스테이킹으로 보안을 유지합니다. 스테이킹은 이자가 나온다는 의미도 있지만, 더 중요한 건 ETH가 잠기면서 유통 물량이 줄 수 있다는 점입니다. 이 경로가 강해지면 ETH는 단순 가스 토큰이 아니라 네트워크 운영에 필요한 기본 자산에 가까워집니다. 다만 여기서도 질문이 남습니다. 스테이킹이 강하게 유지되려면, 이더리움이 정산 레이어로서 핵심 자리를 오래 가져가야 합니다. L2가 커져도 시스템 리스크의 바닥이 L1에 쌓이고, 최종 정산과 보안을 L1이 계속 책임지는 구조가 굳어지면 스테이킹 수요가 유지될 수 있습니다. 반대로 L1이 얇은 정산만 남는 구조로 굳어지면 스테이킹이 계속 강하다고 단정하기 어려운 구간이 올 수도 있다고 봅니다. 4) 담보/준비자산: ETH 가격 논리를 다시 강하게 만들 수 있는 축입니다 제가 ETH를 볼 때 결국 돌아오는 질문은 이겁니다. ETH가 단순 가스 토큰을 넘어, 온체인 금융에서 기본 담보로 굳어질 수 있느냐입니다. DeFi에서는 이미 ETH가 기본 담보로 쓰여왔습니다. 스테이블코인이 커지고, RWA가 들어오고, 기관이 들어올수록 결국 “무엇을 담보로 잡을 것인가”가 더 중요해집니다. 담보는 유동성이 깊어야 하고, 신뢰가 있어야 하며, 청산이 가능해야 합니다. 이 조건을 만족할 수 있는 자산은 결국 몇 개 안 남습니다. 그래서 저는 ETH가 정산 레이어를 넘어 담보 레이어로 굳어질 경우, L2가 커져도 ETH가 약해지는 게 아니라 오히려 더 강해질 수 있다고 봅니다. 다만 이것도 자동은 아닙니다. 담보가 스테이블로만 굳어질 수도 있고, 담보가 BTC로 더 쏠릴 수도 있고, 규제나 사고, 신뢰 문제가 반복되면 기관은 ETH를 담보로 잡는 데 주저할 수도 있습니다. 결론 ETH의 적정 가격은 모르겠습니다. 다만 이더리움이 쉽게 사라질 코인이라고 보지는 않습니다. 그래서 소량만 담아보려고 합니다. Solana(SOL) 솔라나의 서사는 명확합니다. 블록체인을 “앱처럼” 쓰게 만들겠다는 서사입니다. 빠르고, 싸고, UX가 좋고, 클릭이 많은 서비스가 돌아가게 하겠다는 방향입니다. 이 서사는 실제로 강합니다. 블록체인이 대중화되려면 결국 결제나 게임이나 소셜처럼 사람이 계속 만지는 서비스가 나와야 한다는 생각이 있기 때문입니다. 그래서 솔라나가 잘 맞는 그림도 뚜렷합니다. 솔라나의 투자 논리는 결국 여기로 수렴합니다. 블록체인이 진짜로 대중 서비스가 될 때, 그 트래픽이 솔라나에 붙는가. 그런데 여기서부터가 가격 질문입니다. 솔라나는 “많이 쓰일수록 좋다”는 서사 자체는 강한데, 그 사용량이 SOL 가격으로 얼마나 남는지는 별개입니다. 솔라나가 강해질수록 수수료는 싸고, UX는 좋아집니다. 하지만 수수료가 싸다는 건 반대로 말하면, 트래픽이 늘어도 토큰에 쌓이는 수익이 얇을 수 있다는 뜻이기도 합니다. 사용자는 늘고 서비스는 커지는데, 그 가치가 앱과 생태계에만 남고 SOL에 강한 매수 압력을 만들지 못하면 성공해도 가격이 애매한 그림이 나올 수 있습니다. 그리고 솔라나는 구조적으로 “모놀리식”의 대가를 같이 안고 갑니다. 모놀리식의 대가 모든 걸 한 체인에서 빠르게 처리하려면, 검증자가 처리해야 할 일이 늘어납니다. 그만큼 하드웨어 요구사항이 올라가고, 참여 장벽이 올라갑니다. 참여 장벽이 올라가면 네트워크는 특정 인프라에 더 의존할 수 있고, 이건 중앙화 논란으로 이어집니다. 저는 분산을 철학이라기보다 리스크 관리라고 봅니다. 한쪽으로 쏠리면 사고가 났을 때 타격이 커집니다. 안정성 이슈 솔라나가 노리는 영역은 “앱처럼” 쓰는 영역입니다. 그런데 앱은 한 번 멈추면 사용자가 떠납니다. 정산 레이어는 느려도 안전하면 된다는 말이 통할 수 있지만, 앱 레이어는 빠른데 멈춘다가 치명적입니다. 그래서 과거의 중단과 불안정 이슈는 단순 과거 사건이 아니라 신뢰 프리미엄에 계속 박히는 리스크라고 느낍니다. 결론 저는 솔라나의 논리는 이해합니다. 다만 제 기준에서는 안정성과 중앙화 리스크가 크고, 트래픽이 늘었을 때 SOL 가격으로 남는 구조가 강하게 확정된 느낌도 부족합니다. 그래서 이번 포트에서는 제외하려 합니다. Chainlink(LINK) 체인링크의 서사는 “표준 인프라”입니다. 블록체인은 체인 안에서 일어난 일만 확실히 아는 시스템입니다. 그런데 금융은 체인 밖 정보가 없으면 굴러가지 않습니다. 가격이 얼마인지, 환율이 얼마인지, 담보 가치가 유효한지, 준비금이 있는지 같은 외부 사실을 체인 안으로 안전하게 넣어주는 역할이 필요합니다. 이게 오라클이고, 체인링크는 그 오라클을 표준으로 만들려는 프로젝트입니다. 오라클이 중요한 이유는 단순합니다. 이 영역은 한 번 사고가 나면 치명적이라서, 프로젝트 입장에서는 검증된 오라클을 쓰려는 유인이 큽니다. 그래서 체인링크가 표준 인프라가 될 가능성은 충분히 있다고 봅니다. 문제는 그 다음입니다. 표준이 되면 LINK 가격이 오르냐는 질문입니다. 저는 여기서 “필요성”과 “가격”을 분리해서 봅니다. 오라클이 필요해지는 것과, 토큰이 가치가 쌓이는 구조는 같은 말이 아닐 수 있기 때문입니다. 제가 보는 갈림길은 두 가지입니다. 1) 오라클 비용이 LINK 수요로 고정되는가 오라클을 쓰는 비용이 늘어도 그 비용이 LINK를 직접 사서 지불하는 방식으로 고정돼 있지 않으면 토큰 보유 수요는 약해질 수 있습니다. 사업자 레벨에서 결제 방식이 추상화되면, “오라클을 쓴다”가 “LINK를 들고 쓴다”로 연결되지 않을 수도 있습니다. 2) 오라클 신뢰를 담보하는 구조가 LINK 잠김을 만들 수 있는가 오라클은 결국 “틀리면 누가 책임지냐”로 수렴합니다. 저는 이 책임을 토큰 담보로 묶는 구조가 커질수록 LINK가 가격으로 남을 수 있다고 봅니다. 반대로 이 담보 구조가 약하면, 표준화와 가격이 분리될 가능성이 큽니다. 결론 저는 체인링크의 필요성은 인정합니다. 다만 LINK가 가격으로 누적되는 구조가 충분히 단단해졌는지는 아직 확신이 부족합니다. 그래서 이번 포트에서는 제외하려 합니다. Ondo Finance(ONDO) Ondo의 서사는 “온체인 달러 수익”입니다. 온체인에서 달러처럼 안정적인 자산을 들고 있으면서도 수익을 받고 싶다는 수요는 직관적입니다. 특히 시장이 불안할수록 사람들은 변동성 대신 금리와 수익률을 찾습니다. 그래서 저는 이 수요 자체는 강하다고 봅니다. 하지만 이 분야는 서사보다 구조가 먼저입니다. RWA는 특히 “토큰이 있냐”보다 “제도와 검증이 있냐”에서 갈립니다. Ondo를 볼 때 제가 걸리는 건 두 가지입니다. 1) 규제, 자격, 유통 제한 RWA는 접근성에서 바로 벽이 생깁니다. 이 분야는 기술보다 제도가 먼저입니다. 상품이 커지려면 신뢰가 쌓여야 하고, 신뢰는 결국 규제와 검증, 운영의 반복에서 나옵니다. 2) 토큰의 밸류 캡처 이건 더 중요합니다. 상품이 커지는 것과 ONDO 토큰이 오르는 것은 항상 같지 않습니다. 상품은 커지는데 수익과 구조가 회사나 플랫폼에만 남고, 토큰은 거버넌스 같은 “있으면 좋은 것”에 머물 수도 있습니다. 저는 RWA에서 가장 위험한 착각이 “RWA가 성장하면 관련 토큰은 다 오른다”라고 생각합니다. 성장은 사업에 남을 수도 있고, 수익은 오프체인 계약과 구조에 남을 수도 있습니다. 토큰이 필수 비용이나 담보로 박혀 있지 않으면 성장과 가격은 쉽게 분리됩니다. 결론 저는 Ondo의 수요 서사는 이해합니다. 다만 지금은 토큰이 가격으로 남는 구조가 충분히 단단하다고 보기 어렵고, RWA 특성상 제도와 운영의 반복이 더 확인돼야 한다고 느낍니다. 그래서 지금은 옵션으로만 보고 매수하지 않으려 합니다. Centrifuge(CFG), Polymesh(POLYX) CFG와 POLYX는 “RWA”로 묶이지만 Ondo와 성격이 다릅니다. 이쪽은 현실 자산을 온체인으로 가져오는 과정 전체를 플랫폼으로 만들려는 프로젝트에 가깝습니다. 저는 이 분야가 어렵다고 느끼는 이유가 명확합니다. “토큰화”라는 말은 쉽지만, 실제로는 발행 이후의 운영이 전부이기 때문입니다. RWA는 운영이 반복될 때 신뢰가 쌓이고, 신뢰가 쌓여야 규모가 붙습니다. 그래서 저는 이쪽을 볼 때 특히 차갑게 봅니다. 1) 발표가 아니라 실제 발행이 꾸준히 늘고 있는가 이 분야는 로드맵보다 실적이 중요합니다. 실제 발행이 지속적으로 늘어나는지부터 봅니다. 2) 발행 이후 상환, 운영, 감사가 반복적으로 돌아가는가 한 번 발행한 다음 조용한 프로젝트는 많습니다. 진짜는 운영이 반복되는 프로젝트입니다. 3) 토큰이 그 과정의 필수 비용이나 담보로 박혀 있는가 플랫폼이 커져도 토큰이 필수 자원 자리를 못 잡으면, 성장은 플랫폼과 사업에 남고 토큰은 남지 않을 수 있습니다. 저는 이 조건이 아직 “확정적으로 강하다”까지는 잘 모르겠습니다. 그래서 지금 당장 확신으로 매수하기보다는, 운영 데이터가 더 쌓이는 걸 먼저 보고 싶습니다. 결론 이쪽은 발표보다 운영이 먼저이고, 토큰이 가격으로 남는 구조가 실제로 확인되는 단계가 와야 매수 논리가 생긴다고 봅니다. 그래서 지금은 확신이 부족해서 구매하지 않으려 합니다. 결론 저는 지금 이 시장을 확신으로 보지 않습니다. 다만 규제 정리와 함께 시장 구조가 바뀌는 구간에서는, 승자와 패자가 갈리면서 자본이 한쪽으로 몰리는 순간이 생길 수 있다고 봅니다. 그래서 저는 코인을 “기술이 좋다”로 사기보다, 서사가 어떻게 가격으로 남는지를 기준으로 보려고 합니다. 지금 제 결론은 단순합니다. 나머지 코인들은 서사는 이해하지만, 지금은 가격으로 남는 구조에 대한 확신이 부족합니다.그래서 이번에는 보류하거나 제외합니다.
벌써 2026년 어느덧 스물여덟 살이 되었습니다. 2019년에 처음 주식을 시작했으니 투자도 벌써 7년 정도 된 것 같습니다.시간이 꽤 빨리 지나갔습니다. 돌이켜 보면 그동안 투자를 하면서 나름대로 포트폴리오도 만들어 보고여러 종목들도 사 봤습니다. 다만 지금 생각해 보면그때 했던 투자 중에는 명확한 이유가 없던 경우도 꽤 많았습니다. 싸 보인다는 이유로 산 종목도 있었고좋은 회사 같다는 느낌만으로 들어간 투자도 있었습니다. 당시에는 나름대로 고민했다고 생각했는데지나고 보면 그냥 감각에 가까웠던 경우도 많았던 것 같습니다. 투자를 하면서 반복해서 느낀 것도 있습니다. 저점이라고 생각했던 자리 아래에는생각보다 더 내려갈 공간이 있었습니다. 반대로 고점이라고 생각했던 가격 위로주가가 계속 올라가는 경우도 있었습니다. 그래서 어느 순간 이런 생각이 들었습니다. 내가 왜 이걸 샀는지 설명할 수 있어야 하지 않을까. 그래서 요즘은 생각이 들 때마다그냥 글로 적어 두려고 합니다. 투자하면서 어떤 생각을 했는지,왜 그런 판단을 했는지나중에 다시 돌아볼 수 있게 말입니다. 지금은 분명 AI 시대입니다 요즘 시장을 보면 한 가지는 확실합니다. 지금은 AI의 시대입니다. OpenAI, Anthropic, Google 같은 회사들이 모델 경쟁을 하고 있고개발 환경도 굉장히 빠르게 바뀌고 있습니다. 예전에는 코드 하나 작성하려면사람이 직접 다 작성해야 했습니다. 지금은 같은 도구들이 나오면서개발 방식 자체가 많이 달라지고 있습니다. 회사에서도 AI 도구를 쓰는 일이 점점 많아지고 있습니다. 문서 정리데이터 분석코드 작성간단한 자동화 작업 예전에는 사람이 직접 하던 일들이이제는 AI에게 넘어가는 경우도 많습니다. 그래서 요즘 회사들에서 이런 이야기도 자주 나옵니다. AI 때문에 생산성이 올라간다.AI 때문에 인력이 줄어든다. 실제로 자동화가 늘어나면서사람이 하던 일이 줄어드는 분야도 있는 것 같습니다. 한편으로는 또 다른 문제도 있습니다. AI가 보안을 위협하는 도구가 되기도 합니다. 예전보다 훨씬 정교한 피싱 메일이 만들어지고취약점을 찾는 작업도 AI가 도와줄 수 있습니다. 그래서 AI는 생산성을 올리기도 하지만동시에 새로운 리스크도 만들어 내는 기술이라고 느껴집니다. 그런데 AI 이야기는 너무 많습니다 요즘 시장을 보면 AI 이야기가 정말 많습니다. 어느 회사든AI를 하고 있다고 말합니다. AI 스타트업도 계속 생기고대기업들도 AI 전략을 이야기합니다. 그런데 개인적으로는이런 생각이 들기 시작했습니다. AI 자체는 이미 너무 많은 사람들이 보고 있는 것 아닐까. 좋은 회사인 건 맞는데주가도 이미 꽤 많이 올라와 있는 경우가 많습니다. 그래서 요즘은 조금 다른 관점으로 보기 시작했습니다. AI가 중요하다는 건 다들 알고 있습니다.그렇다면 그 AI가 실제로 돌아가려면 무엇이 필요할까. 이 질문이 먼저 떠올랐습니다. AI는 결국 물리 위에서 돌아갑니다 AI 모델은 소프트웨어입니다. 하지만 그 모델이 실제로 돌아가려면반드시 물리적인 기반이 필요합니다. 예를 들면 이런 것들입니다. 이게 없으면 AI는 돌아가지 않습니다. 모델이 아무리 좋아도서버가 없으면 실행할 수 없습니다. 서버가 있어도전기가 없으면 멈춥니다. AI 경쟁이 심해질수록오히려 이런 물리적인 인프라가 더 중요해지는 느낌도 있습니다. 최근에 일론 머스크가 이런 말을 했던 것을 본 적이 있습니다. 처음 들었을 때는조금 과장된 말처럼 들리기도 했습니다. 그런데 생각해 보면완전히 틀린 말은 아닌 것 같습니다. AI가 커질수록결국 전력과 인프라가 병목이 될 가능성이 있기 때문입니다. 그래서 요즘은AI 자체보다 AI가 돌아가기 위한 기반 산업도 같이 보려고 합니다. 전기를 기준으로 보면 흐름이 조금 보입니다 개인적으로는 전력 흐름을 기준으로 보면AI 산업 구조가 조금 더 이해가 쉬운 것 같습니다. 아주 단순하게 나누면 이런 식입니다. 완벽한 구분은 아니지만이렇게 보면 산업 구조가 조금 더 눈에 들어옵니다. 예를 들어 전기를 만드는 쪽은전력 회사들이 있습니다. 전기를 보내는 쪽은송전망과 전력 인프라 회사들이 있습니다. 전기를 저장하는 쪽은배터리와 ESS 같은 분야입니다. 전기를 연산으로 바꾸는 곳은데이터센터입니다. 그리고 같은 전기로 더 많은 일을 하는 쪽은전력 관리나 냉각 기술 같은 영역입니다. 이렇게 보면AI 산업이 단순히 모델 경쟁만은 아니라는 것이 조금 보입니다. 물론 인프라가 전부는 아닙니다 다만 인프라만이 미래라고 생각하는 것은 아닙니다. AI 산업은 훨씬 넓습니다. 이런 영역들도 계속 커질 가능성이 있습니다. 특히 로봇 쪽은 개인적으로 꽤 흥미롭게 보고 있습니다. AI가 발전하면서로봇과 연결되는 사례도 점점 많아지고 있습니다. AI가 뇌 역할을 하고로봇이 몸 역할을 하는 구조입니다. 이 조합이 앞으로 어떻게 발전할지는아직 아무도 정확히 모르는 것 같습니다. 그래서 요즘은AI를 하나의 산업이라기보다 여러 산업을 동시에 바꾸는 기술이라고 보는 편이 맞는 것 같습니다. 코인도 완전히 바깥에 있지는 않습니다 처음에는 전력이나 데이터센터 같은 이야기는 주식의 영역이라고만 생각했습니다.코인은 그와는 조금 다른 세계라고 생각했기 때문입니다. 그런데 보다 보니 완전히 분리된 영역은 아닌 것 같기도 합니다. 블록체인도 결국 서버에서 돌아갑니다. 그리고 돈이 이동하고 정산이 이루어지는 구조에서는 코인이 실제로 사용되는 구간도 있습니다. 예를 들어 비트코인은 가치 저장 자산으로 이야기되기도 하고, 이더리움은 디파이 기반 네트워크로 많이 사용됩니다. 또 스테이블코인은 온체인에서 실제 결제나 정산에 사용되는 경우도 많습니다. 다만 이 부분은 아직 변수가 많다고 생각합니다. 규제도 있고 기술 경쟁도 있고 시장 구조도 계속 바뀌고 있기 때문입니다. 그래서 개인적으로는 코인을 모든 곳에 억지로 연결하려고 하지는 않습니다. 다만 금융 레일이라는 관점에서는 어떤 역할을 할 수 있을지 계속 지켜보고 있습니다. AI 이야기를 하다 보면 결국 기술 경쟁 이야기로 흘러가기 쉽습니다.하지만 요즘은 오히려 그 기술이 실제로 돌아가기 위해 필요한 것들을 더 보게 됩니다. 전력, 데이터센터, 반도체, 네트워크 같은 것들입니다. AI가 계속 발전한다면 이런 인프라들은 결국 같이 커질 수밖에 없을 것 같습니다. 그 위에서 소프트웨어도 커지고 자동화도 늘어나고 로봇 같은 새로운 산업들도 붙을 가능성이 있습니다. 그래서 요즘은 시장을 볼 때 AI라는 단어 하나만 보기보다는 그 주변에서 같이 움직이는 산업들을 같이 보려고 합니다. 아직 저도 확신이 있는 것은 아닙니다. 다만 예전보다는 조금 더 구조를 보려고 하고 있습니다. 앞으로도 생각이 정리되면 이런 이야기들을 하나씩 정리해 보려고 합니다.
Part 8 of 8 [제목]: 실전 프로젝트: 배운 것 총동원해서 자동화 스크립트 만들기[이번 파트 목표]: 1~7편에서 배운 모든 것을 활용해, 실무에서 쓸 법한 자동화 리포트 스크립트를 완성한다. 이것도 미검증상태 이번에 배울 것 드디어 마지막 편이야! 지금까지 배운 변수, 조건문, 반복문, 배열, 함수, DB 탐색, 파일 입출력을 모두 엮어서 '특정 조건에 맞는 파이프를 찾아 파일로 정리하는' 완전한 자동화 스크립트를 만들어 볼 거야. 왜 필요한데? 실무에서는 이런 일이 정말 많아. "이 구역에 있는 파이프 중에, 직경(BORE)이 100mm 넘는 것들만 목록으로 뽑아주세요." 같은 요청 말이야. 수백, 수천 개를 일일이 클릭해서 확인할 순 없잖아? 이럴 때 PML 스크립트 하나면 커피 한잔 마시는 동안 컴퓨터가 알아서 다 해줄 수 있지. 이게 바로 우리가 PML을 배우는 이유야! 핵심 개념: 프로젝트 설계하기 우리가 만들 스크립트는 이런 순서로 작동할 거야. 어때? 지금까지 배운 내용이 다 들어있지? 이제 코드로 옮겨보자. 코드 예제 (따라하기) 하나의 완성된 코드를 단계별로 나눠서 설명해 줄게. 전체 코드를 pipe_report.pmlfnc 같은 파일로 저장하고 로드해서 실행해 봐. 1단계: 기본 틀과 설정 잡기 먼저, 전체 로직을 담을 함수를 만들고 필요한 설정값들을 변수로 빼두는 거야. 이렇게 하면 나중에 조건을 바꾸기 쉬워. -- 전체 로직을 담을 메인 함수 define function !!runPipeReport() -- 1. 설정값 정의 !outputFile = 'C:\temp\pipe_report.txt' -- 결과가 저장될 파일 경로 !Threshold = 100 !boreThreshold = !Threshold.bore() $P Report generation started... $P Bore threshold: $!boreThreshold $P Output file: $!outputFile -- (이후 코드는 여기에 계속 추가될 거야) endfunction 2단계: 데이터 수집 및 처리 루프 만들기 이제 !!collectAllFor 함수로 현재 요소(CE) 아래의 모든 파이프를 수집하고, DO VALUES로 반복문을 돌릴 준비를 하자. 결과를 담을 빈 배열도 미리 만들어둬. define function !!runPipeReport() !outputFile = 'C:\temp\pipe_report.txt' !Threshold = 100 !boreThreshold = !Threshold.bore() -- ... (이전 코드 생략) ... -- 2. 결과 저장용 배열 생성 !foundPipes = object ARRAY() -- 3. 현재 위치(CE)에서 모든 PIPE 수집 !allPipes = !!collectAllFor('PIPE', '', !!ce) !totalCount = !allPipes.size() $P Found $!totalCount total pipes. Processing... -- 4. 수집된 파이프들을 하나씩 확인 do !pipe values !allPipes if (!pipe.bore GT !boreThreshold) then -- 조건에 맞으면 배열에 추가 !pipeInfo = 'Name: ' + !pipe.name + ', Bore: ' + !pipe.bore.string() !foundPipes.append(!pipeInfo) endif enddo -- (이후 코드는 여기에 계속 추가될 거야) endfunction 3단계: 파일에 결과 쓰고 최종 보고하기 이제 조건에 맞는 파이프 정보가 담긴 !foundPipes 배열을 파일로 쓸 차례야. 파일 작업은 에러가 날 수 있으니 HANDLE 블록으로 감싸주는 센스! define function !!runPipeReport() !outputFile = 'C:\temp\pipe_report.txt' !Threshold = 100 !boreThreshold = !Threshold.bore() !foundPipes = object ARRAY() !allPipes = !!collectAllFor('PIPE', '', !!ce) !totalCount = !allPipes.size() -- ... (데이터 처리 루프 코드 생략) ... do !pipe values !allPipes if (!pipe.bore GT !boreThreshold) then !pipeInfo = 'Name: ' & !pipe.name & ', Bore: ' & !pipe.bore.string() !foundPipes.append(!pipeInfo) endif enddo -- 5. 파일에 결과 쓰기 (에러 처리 포함) handle ANY -- 파일 열기 (쓰기 모드) !file = object FILE(!outputFile, 'WRITE') -- 헤더 추가 !file.writeString('--- Pipe Report ---') !file.writeString('Found pipes with BORE greater than ' & !boreThreshold.string()) !file.writeString('-------------------') -- 배열에 저장된 내용을 한 줄씩 파일에 쓰기 do !line values !foundPipes !file.writeString(!line) enddo -- 파일 닫기 (아주 중요!) !file.close() elsehandle NONE -- 정상 처리 시 메시지 $P Successfully wrote $!foundPipes.size() items to file. endhandle -- 6. 최종 결과 요약 $P --- Summary --- $P Total pipes checked: $!totalCount $P Pipes matching criteria: $!foundPipes.size() $P Report finished. endfunction 이제 이 함수를 로드하고 명령창에 !!runPipeReport()를 실행해 봐. C:\temp 폴더에 pipe_report.txt 파일이 멋지게 생성될 거야! 자주 하는 실수 ❌ 실수 1: 파일 닫기(close()) 까먹기 -- ❌ 잘못된 코드 !file = object FILE('C:\temp\test.txt', 'WRITE') !file.writeString('hello') -- !file.close() 를 안하면 파일이 계속 열려있거나 내용이 제대로 안 써질 수 있어. -- ✅ 올바른 코드 !file = object FILE('C:\temp\test.txt', 'WRITE') !file.writeString('hello') !file.close() -- 작업이 끝나면 무조건 닫아주기! ❌ 실수 2: 반복문 안에서 파일 열고 닫기 -- ❌ 비효율적인 코드 do !pipe values !foundPipes !file = object FILE('C:\temp\report.txt', 'APPEND') -- 매번 열고 !file.writeString(!pipe.name) !file.close() -- 매번 닫고... 너무 느려! enddo -- ✅ 올바른 코드 !file = object FILE('C:\temp\report.txt', 'WRITE') -- 처음에 한 번만 열고 do !pipe values !foundPipes !file.writeString(!pipe.name) enddo !file.close() -- 마지막에 한 번만 닫기! 연습 문제
Part 7 of 8 [제목]: 에러 처리와 파일 다루기, 이젠 쫄지 말자![이번 파트 목표]: 코드가 터져도 괜찮아! 에러를 잡고, 외부 파일을 읽고 쓰는 법을 배울 거야. 요번글은 PML AI 로 뽑아내고 아직 검증안했습니다 1. 이번에 배울 것 안녕! 지난 파트까지 잘 따라왔다면 이제 제법 PML과 친해졌을 거야. 이번엔 프로그램의 안전벨트, handle 에러 처리와 외부 세계와 소통하는 창구, FILE 객체 사용법을 배울 거야. 이걸 배우면 네 코드는 훨씬 더 안정적이고 강력해질 거야! 2. 왜 필요한데? 상상해봐. 네가 만든 멋진 자동화 매크로가 외부 텍스트 파일(pipe_list.txt)에서 파이프 목록을 읽어와서 한 번에 속성을 바꿔준다고 치자. 동료한테 "이거 써봐!" 하고 줬는데, 동료가 실수로 그 파일을 지웠네? 그럼 어떻게 될까? File not found 에러가 뻥! 터지면서 프로그램이 그냥 멈춰버릴 거야. 동료는 "이거 왜 안돼?" 하고 널 찾아오겠지. 민망하잖아. 이럴 때 필요한 게 바로 에러 처리야. 파일이 없으면 "파일이 없는데요? 확인 좀 해주세요." 라고 친절하게 알려주고 프로그램을 안전하게 종료시키는 거지. 그리고 파일 다루기는 애초에 그 pipe_list.txt 같은 외부 파일을 읽고 쓸 수 있게 해주는 기술이고. 둘은 환상의 짝꿍이야! 3. 핵심 개념 설명 프로그램의 안전망, handle! handle은 말 그대로 '처리하다'라는 뜻이야. 코드 실행 중에 뭔가 문제가 생겼을 때(에러 발생), 프로그램이 죽지 않고 우리가 미리 정해놓은 대처를 하게 만드는 안전망 같은 거지. 기본 구조는 이래. handle ANY -- 에러가 날 것 같은 위험한 코드 elsehandle NONE -- 에러 없이 성공했을 때 실행할 코드 endhandle 만약 어떤 에러가 났는지 궁금하면 !!error라는 전역 변수를 확인하면 돼. 에러에 대한 정보가 담겨있거든. 외부 파일과 대화하기, FILE 객체 PML 세상 밖의 파일들(txt, csv 등)과 데이터를 주고받으려면 FILE이라는 객체가 필요해. 이건 마치 우리 코드와 컴퓨터 파일 시스템을 연결해주는 '전화기' 같은 거야. 파일 작업은 보통 4단계로 이뤄져. 주요 open 모드: 4. 코드 예제 (따라하기) 자, 이제 직접 코드를 짜보면서 익혀보자. 예제 1: 안전하게 파일 읽어보기 바탕화면에 my_data.txt 파일이 있다고 상상하고 코드를 짜 볼 거야. 처음엔 파일이 없어서 에러가 나고, 두 번째엔 파일을 만들고 실행해서 성공하는 걸 보자. -- 1. 파일 경로를 변수에 저장 !filePath = 'C:\Users\Public\Desktop\my_data.txt' -- 2. handle로 안전하게 파일 열기 시도 handle ANY -- 이 안에서 에러가 나면 바로 아래 elsehandle로 점프! !file = object FILE(!filePath) !file.open('READ') elsehandle NONE -- 에러가 없었을 때 실행되는 곳 $P '$!filePath' 파일을 성공적으로 열었습니다! -- 여기서 파일 읽기 작업을 하면 돼. !file.close() -- 작업 끝났으면 닫기! endhandle -- 3. 만약 에러가 났다면, !!error 변수로 확인 가능 if (!!error.isSet()) then $P 에러 발생: $(!!error.text) endif 실행 결과 (파일이 없을 때): 에러 발생: File C:\Users\Public\Desktop\my_data.txt not found 이제 바탕화면에 my_data.txt 파일을 직접 만들고 아무 내용이나 적어봐. 그리고 위 코드를 다시 실행해봐. 실행 결과 (파일이 있을 때): 'C:\Users\Public\Desktop\my_data.txt' 파일을 성공적으로 열었습니다! 어때? handle 덕분에 프로그램이 죽지 않고 상황에 맞게 동작하지? 예제 2: 파일에 내 정보 기록하기 이번엔 내 이름과 현재 시간을 파일에 써보자. !logPath = 'C:\E3D_log.txt' !file = object FILE(!logPath) -- 'WRITE' 모드는 파일이 있으면 뒤에 이어서 써줘. !file.open('WRITE') -- 현재 시간을 가져오는 내장 함수 !now = !!getDateTime('datetime', '', ' ') -- 파일에 쓸 내용 만들기 !logMessage = 'User: Admin, Time: ' & !now -- 파일에 한 줄 쓰기 !file.writeString(!logMessage) -- 아주 중요! 꼭 닫아주기 !file.close() $P '$!logPath' 파일에 로그를 기록했습니다. 이제 C:\ 드라이브에 가보면 E3D_log.txt 파일이 생겼을 거고, 열어보면 방금 기록한 내용이 있을 거야. 코드를 여러 번 실행하면 내용이 계속 추가되는 것도 확인해봐! 5. 자주 하는 실수 ❌ 실수 1: 에러 처리만 하고 성공 처리를 안 할 때 -- ❌ 나쁜 코드 handle ANY !file = object FILE('a.txt') !file.open('READ') -- 성공했을 때 뭘 할 건데? 알 수가 없네. endhandle $P 에러가 났나? 성공했나? 이러면 안 돼! 에러가 안 났을 때 뭘 해야 할지가 코드에 없어서 로직이 꼬여. -- ✅ 좋은 코드 handle ANY !file = object FILE('a.txt') !file.open('READ') elsehandle NONE $P 성공! 이제 파일을 처리하자. !file.close() endhandle 이렇게 하자! elsehandle NONE을 사용해서 성공했을 때의 경로를 명확히 해주는 게 좋아. ❌ 실수 2: 파일 작업하고 .close() 안 하기 -- ❌ 절대 금지! !file = object FILE('C:\temp.txt') !file.open('OVERWRITE') !file.writeString('중요 데이터') -- !file.close() 를 까먹었다! 이러면 안 돼! 데이터가 파일에 제대로 안 써질 수도 있고, 파일이 계속 열려 있어서 다른 프로그램이 접근 못하는 문제가 생길 수 있어. -- ✅ 좋은 코드 !file = object FILE('C:\temp.txt') !file.open('OVERWRITE') !file.writeString('중요 데이터') !file.close() -- 작업이 끝나면 무조건 닫는다! 이렇게 하자! open()을 했으면 close()는 묻지도 따지지도 말고 세트로 따라와야 해. 6. 연습 문제 이제 네 차례야! 직접 해봐야 실력이 늘어.
Part 6 of 8 [제목]: E3D 모델링의 핵심, DB 탐색하고 속성 파헤치기[이번 파트 목표]: E3D 데이터베이스에서 원하는 요소를 찾고, 그 요소의 정보를 읽는 방법을 배운다. 1. 이번에 배울 것 오늘은 E3D 데이터베이스라는 거대한 도서관에서 내가 원하는 책(요소)을 정확히 찾아내고, 그 책의 정보(속성)를 읽는 방법을 배울 거야. 2. 왜 필요한데? 상황을 상상해 봐. 상사가 갑자기 "우리 프로젝트에 있는 100mm보다 큰 파이프들 전부 찾아서 목록 만들어 와!"라고 시켰어. 수천, 수만 개의 파이프를 눈으로 하나씩 클릭해서 확인할 거야? 절대 아니지! PML을 사용하면 단 몇 줄의 코드로 이런 작업을 10초 만에 끝낼 수 있어. 특정 조건의 부재를 찾고, 속성을 읽고, 심지어 한 번에 수정하는 것까지! 이게 바로 PML DB 탐색의 힘이야. 3. 핵심 개념 설명 CE: 너의 현재 위치 !CE는 'Current Element'의 약자야. 지금 네가 E3D 화면에서 선택한 바로 그 요소를 가리키는 특별한 변수지. 네가 파이프를 클릭하면 !CE는 그 파이프가 되고, 구조물을 클릭하면 !CE는 그 구조물이 돼. 앞으로 우리가 탐색을 시작할 출발점이 될 거야. -- 현재 선택한 요소의 이름을 알고 싶을 때 !CE = CE $P 현재 요소 이름: !CE.Name 속성(Attribute): 요소의 주민등록증 모든 E3D 요소(파이프, 장비, 노즐 등)는 자신만의 정보, 즉 '속성'을 가지고 있어. 이름(NAME), 재질(MATREF), 구경(BORE), 위치(POS) 같은 것들이지. 이 속성들은 .(점)을 찍어서 접근할 수 있어. -- 현재 선택한 파이프의 구경(Bore)을 알고 싶다면? !CE = CE !currentBore = !CE.Bore $P 현재 파이프 구경: $!currentBore !!collectAllFor(): E3D의 검색 엔진 이게 오늘 배울 것의 하이라이트야. !!collectAllFor() 함수는 E3D 데이터베이스 전체를 뒤져서 네가 원하는 요소들을 싹 긁어모아 주는 강력한 검색 도구야. 이 함수는 3개의 중요한 정보를 필요로 해. !!collectAllFor('타입', '조건', '검색 시작 위치') 4. 코드 예제 (따라하기) 자, 이제 직접 코드를 짜면서 감을 익혀보자. 목표: 현재 위치(SITE) 아래에 있는 모든 파이프 중에서, 구경(BORE)이 150mm 이상인 것들의 이름과 구경을 출력하기 -- 1. 먼저 현재 위치(SITE) 아래에 있는 모든 PIPE를 찾아보자. -- 타입: 'PIPE', 조건: 없음, 시작위치: !CE (현재 선택한 SITE) !allPipes = !!collectAllFor('PIPE', '', CE) -- 찾은 파이프가 몇 개인지 확인 !pipeCount = !allPipes.size() $P 찾은 파이프 개수: $!pipeCount -- 2. 찾은 파이프 묶음(Collection)을 하나씩 돌면서 정보를 확인하자. -- DO VALUES 구문은 Collection을 순회할 때 아주 유용해! $P --- 150mm 이상 파이프 목록 --- do !pipe values !allPipes -- 3. 각 파이프의 구경(Bore)을 확인해서 150 이상인지 검사 if (!pipe.Bore GE 150) then -- 4. 조건에 맞으면 이름과 구경을 출력 !pipeName = !pipe.Name !pipeBore = !pipe.Bore $P 이름: $!pipeName, 구경: $!pipeBore endif enddo $P --- 검색 완료 --- 실행 방법: 5. 자주 하는 실수 실수 1: !!collectAllFor 인자 개수 틀리기 ❌ 잘못된 코드 -- 3번째 인자(시작 위치)를 빼먹음 !pipes = !!collectAllFor('PIPE', 'BORE GT 100') -- (에러 발생) ✅ 올바른 코드 -- 시작 위치 CE 또는 WORLD 등을 반드시 명시해야 해 !pipes = !!collectAllFor('PIPE', 'BORE GT 100', CE) 실수 2: 비교 연산자 == 사용하기 PML에서는 같음을 비교할 때 ==가 아니라 EQ를 쓴다는 거, 이제는 익숙해졌지? ❌ 잘못된 코드 if (!pipe.Name == '/PIPE-001') then -- 에러! $P 찾았다! endif ✅ 올바른 코드 if (!pipe.Name EQ '/PIPE-001') then $P 찾았다! endif 6. 연습 문제
PML 초보자 가이드: Part 5 of 8 [제목]: 함수와 객체로 코드 재활용하기 [이번 파트 목표]: 반복되는 코드를 함수로 만들고, 나만의 데이터 타입을 객체로 정의할 수 있다. 1. 이번에 배울 것 오늘은 똑같은 코드를 계속 복사-붙여넣기 하지 않도록, 코드를 '재활용'하는 두 가지 핵심 기술, 함수(Function)와 객체(Object)에 대해 배울 거야. 이걸 배우면 코드가 훨씬 깔끔해지고 관리하기 쉬워질 거야! 2. 왜 필요한데? 상황을 하나 상상해보자. 파이프의 단면적을 계산하는 코드를 짰어. (반지름 * 반지름 * 3.14). 그런데 프로젝트 여기저기서 이 계산이 100번이나 필요한 거야. 그럼 이 코드를 100번 복사해서 붙여넣을 거야? 만약 나중에 계산 공식이 반지름 * 반지름 * 3.14159로 더 정확하게 바뀌면? 100군데를 전부 찾아서 고쳐야 해. 완전 끔찍하지? 이럴 때 함수를 쓰는 거야. !!getPipeArea()라는 '나만의 명령어'를 하나 만들어두면, 필요할 때마다 이 명령어만 부르면 돼. 수정도 한 군데만 하면 끝! 객체는 여기서 한 발 더 나아간 개념이야. 파이프 하나에 이름, 직경, 재질, 위치 등 여러 정보가 있잖아? 이걸 각각의 변수 !pipeName, !pipeBore, !pipeMaterial로 관리하면 너무 흩어져 있어서 헷갈려. 객체는 이 모든 정보를 '파이프'라는 하나의 데이터 꾸러미로 묶어주는 역할을 해. 3. 핵심 개념 설명 함수 (Function): '나만의 명령어' 만들기 함수는 특정 작업을 수행하는 코드 덩어리에 이름을 붙여놓은 거야. 레고 블록처럼, 한번 만들어두면 필요할 때마다 가져다 쓸 수 있어. -- 함수 기본 구조 define function !!나만의함수이름(!입력값1 is 타입, !입력값2 is 타입) is 반환타입 -- 여기서 작업 수행 !결과 = !입력값1 + !입력값2 return !결과 endfunction 객체 (Object): '나만의 데이터 꾸러미' 만들기 객체는 연관된 데이터(변수)와 기능(함수)을 하나로 묶은 거야. 우리만의 새로운 데이터 타입을 만드는 거지. -- 객체 기본 구조 define object 나만의객체이름 -- 데이터들 (멤버) member .데이터1 is STRING member .데이터2 is REAL -- 생성자 (초기 설정) define method .나만의객체이름() !this.데이터1 = '기본값' !this.데이터2 = 0 endmethod -- 기능들 (메서드) define method .기능1() $P '데이터1의 값은 ' & !this.데이터1 endmethod endobject 4. 코드 예제 (따라하기) 이제 직접 코드를 짜면서 익혀보자. 1단계: 간단한 함수 만들기 두 숫자를 더하는 간단한 함수를 만들어 볼게. -- 두 숫자를 더해서 결과를 반환하는 함수 정의 define function !!addNumbers(!num1 is REAL, !num2 is REAL) is REAL !result = !num1 + !num2 return !result endfunction -- 함수 호출(사용)하기 !sum = !!addNumbers(10, 20) $P 10 + 20 = $!sum -- 결과: 10 + 20 = 30 !anotherSum = !!addNumbers(5.5, 2.3) $P 5.5 + 2.3 = $!anotherSum -- 결과: 5.5 + 2.3 = 7.8 2단계: 나만의 객체 정의하기 이번엔 파이프 데이터를 담을 PipeData라는 객체를 만들어보자. -- PipeData 객체 정의 define object PipeData -- 멤버 변수 선언 member .name is STRING member .bore is REAL member .material is STRING -- 생성자 메서드 (객체 생성 시 초기화) define method .PipeData() !this.name = 'UNSET' !this.bore = 0 !this.material = 'A106' endmethod endobject 3단계: 객체에 기능(메서드) 추가하기 PipeData 객체에 자신의 정보를 출력하는 메서드와 단면적을 계산하는 메서드를 추가해볼게. define object PipeData member .name is STRING member .bore is REAL member .material is STRING define method .PipeData() !this.name = 'UNSET' !this.bore = 0 !this.material = 'A106' endmethod -- 자신의 정보를 출력하는 메서드 define method .printInfo() $P --- Pipe Info --- $P Name: $!this.name $P Bore: $!this.bore $P Material: $!this.material $P ----------------- endmethod -- 단면적을 계산해서 반환하는 메서드 define method .getArea() is REAL !radius = !this.bore / 2 !area = !radius * !radius * 3.14159 return !area endmethod endobject 4단계: 객체 생성하고 사용하기 이제 우리가 만든 PipeData 객체를 실제로 만들고 사용해보자. -- 1. PipeData 객체 생성 !myPipe = object PipeData() -- 2. 멤버 변수에 값 할당 !myPipe.name = '/P100-B-8' !myPipe.bore = 150.0 -- 3. 메서드 호출 !myPipe.printInfo() !pipeArea = !myPipe.getArea() $P Pipe Area is: $!pipeArea 5. 자주 하는 실수 ❌ 객체 생성 시 object 키워드 누락 다른 언어 습관 때문에 object를 빼먹는 경우가 많아. PML에서는 필수야! -- ❌ 잘못된 코드 !myPipe = PipeData() -- 에러! -- ✅ 올바른 코드 !myPipe = object PipeData() ❌ 메서드 안에서 !this 빼먹기 메서드 안에서 같은 객체의 다른 멤버나 메서드에 접근할 땐 !this를 꼭 붙여줘야 해. define object MyObject member .value is REAL define method .getValue() is REAL -- ❌ 잘못된 코드 -- return .value -- 에러! -- ✅ 올바른 코드 return !this.value endmethod endobject ❌ 함수에서 return 안 하기 함수가 값을 돌려주기로 약속(is REAL 처럼)했는데 return을 안 하면, 함수를 호출한 쪽은 UNSET 값을 받게 돼서 에러가 날 수 있어. define function !!badFunc() is REAL !result = 100 -- return을 안 함 endfunction !value = !!badFunc() $P Value is: $!value -- Value is: UNSET if (!value GT 50) then -- UNSET과 비교하면 에러 발생! $P Greater than 50 endif 6. 연습 문제